home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 726-750 / 731 / qmouse / qmouse.s < prev    next >
Text File  |  1995-03-18  |  28KB  |  1,454 lines

  1. ;QMouse.s
  2. ;Written by Dan Babcock
  3.  
  4. ;This source was assembled with Macro68 release 3.
  5.  
  6.     exeobj
  7.     objfile    'c:QMouse'
  8.     MC68000
  9.     multipass
  10.  
  11.     IFND    SYS
  12. SYS    macro
  13.     jsr    _LVO\1(a6)
  14.     endm
  15.     ENDC
  16.  
  17.     IFND    _custom
  18. _custom    equ    $dff000
  19.     ENDC
  20.  
  21.     IFND    _LVOSystemTagList
  22. _LVOSystemTagList    equ    -$25E
  23.     ENDC
  24.  
  25. SCREENLISTSIZE    equ    32    ;maximum number of screens to keep track of
  26. POINTERLISTSIZE    equ    32
  27. HANDLERPRI    equ    60    ;priority of input.device handler
  28. MaxCopperSize    equ    500
  29.  
  30. SysBackground    equ    $e    ;offset into gb_copinit copper list
  31. WindowStart    equ    $0    ;offset into LOF copper list
  32. WaitLineOffset    equ    $68    ;offset into gb_copinit for my cwait
  33. DefColor    equ    $fff    ;white
  34. WaitLine    equ    $16
  35.  
  36.     move.l    4,a6
  37.     cmp.w    #37,LIB_VERSION(a6)
  38.     bhs    GoodVersion
  39.  
  40. ;Print an error message - the user doesn't have 2.0
  41.     lea    DosName(pc),a1
  42.     SYS    OldOpenLibrary
  43.     tst.l    d0
  44.     beq    ErrEnd
  45.     move.l    d0,a6
  46.     SYS    Output
  47.     move.l    d0,d1
  48.     moveq    #EndSorry-Sorry,d3
  49.     lea    Sorry(pc),a0
  50.     move.l    a0,d2
  51.     SYS    Write
  52.     move.l    a6,a1
  53.     move.l    4,a6
  54.     SYS    CloseLibrary
  55. ErrEnd:    moveq    #RETURN_FAIL,d0
  56.     rts
  57.  
  58.     dc.b    '$VER: QMouse 2.20 (13.9.92)',$a,0
  59. Sorry:    dc.b    'Sorry, this program requires Kickstart 2.0!',$a,0
  60. EndSorry:    even
  61.  
  62. GoodVersion:
  63.  
  64. ;Allocate global data structure
  65.     move.l    #Data_Sizeof,d0
  66.     move.l    #MEMF_CLEAR,d1
  67.     SYS    AllocMem
  68.     tst.l    d0
  69.     beq    ErrEnd
  70.     move.l    d0,a5
  71.     lea    GlobalPtr(pc),a0
  72.     move.l    a5,(a0)
  73.  
  74. ;Allocate chip RAM data.
  75.     move.l    #CData_Sizeof,d0
  76.     move.l    #MEMF_CLEAR+MEMF_CHIP,d1
  77.     SYS    AllocMem
  78.     move.l    d0,ChipData(a5)
  79.     beq    CleanUp
  80.  
  81. ;Initialize static data
  82.     move.b    #HANDLERPRI,InputInterrupt+LN_PRI(a5)
  83.     move.l    a5,InputInterrupt+IS_DATA(a5)
  84.     moveq    #1,d0
  85.     move.l    d0,ClickCount(a5)    ;***BUG: WAS A1 (trashing memory)
  86.                 ;THANKS to Chris Schneider for finding
  87.                 ;it!!!!!!!!!!!!!!!!
  88.  
  89. ;Open libraries
  90.     lea    LibTable(pc),a2
  91.     move.l    a2,a3
  92.     moveq    #NumLibs-1,d2
  93. .OLibLoop:
  94.     move.w    (a2)+,a1
  95.     add.l    a3,a1
  96.     SYS    OldOpenLibrary
  97.     move.w    (a2)+,a0
  98.     add.l    a5,a0
  99.     move.l    d0,(a0)
  100.     beq    CleanUp
  101.     dbra    d2,.OLibLoop
  102.  
  103. ;Parse command line
  104.     lea    Template(pc),a0
  105.     move.l    a0,d1
  106.     lea    Options(a5),a0
  107.     move.l    a0,d2
  108.     moveq    #0,d3    ;no custom rdarg structure
  109.     move.l    DosBase(a5),a6
  110.     SYS    ReadArgs
  111.     move.l    d0,ArgPtr(a5)
  112.     beq    CleanUp
  113.     move.l    4,a6
  114.  
  115. ;Process QUIT option, if selected.
  116.     tst.l    QuitOption(a5)
  117.     beq    .SkipQuit
  118.     lea    ProcName(pc),a1
  119.     SYS    FindTask
  120.     tst.l    d0
  121.     beq    CleanUp
  122.     move.l    d0,a1
  123.     move.l    TC_Userdata(a1),a0
  124.     move.l    QuitSig(a0),d0
  125.     SYS    Signal    ;tell task to quit
  126.     bsr    CleanUp
  127.     bra    .Exit
  128. .SkipQuit:
  129.  
  130. ;If already installed, kill the existing process.
  131.     lea    ProcName(pc),a1
  132.     SYS    FindTask
  133.     tst.l    d0
  134.     beq    .NotInstalled
  135.     move.l    d0,a1
  136.     move.l    TC_Userdata(a1),a0
  137.     move.l    QuitSig(a0),d0
  138.     SYS    Signal    ;tell task to quit
  139.  
  140.     moveq    #26,d2
  141. .Kill:    subq.l    #1,d2
  142.     beq    .Exit
  143.     move.l    DosBase(a5),a6
  144.     moveq    #2,d1
  145.     SYS    Delay
  146.     lea    ProcName(pc),a1
  147.     move.l    4,a6
  148.     SYS    FindTask
  149.     tst.l    d0
  150.     bne    .Kill
  151. .NotInstalled:
  152.  
  153. ;Get stack for command.
  154.     move.l    DosBase(a5),a6
  155.     SYS    Cli
  156.     move.l    d0,a0
  157.     move.l    cli_DefaultStack(a0),d0
  158.     lsl.l    #2,d0
  159.     lea    CmdStackSize(pc),a0
  160.     move.l    d0,(a0)
  161.     move.l    4,a6
  162.  
  163. ;Copy resident part of code into allocated memory
  164.     lea    StartAllocCode(pc),a0    ;source
  165.     lea    ResidentCode(a5),a1    ;destination
  166.     move.l    #ResidentCodeSize,d0    ;size
  167.     SYS    CopyMem
  168.     SYS    CacheClearU    ;for 020/030/040
  169.  
  170. ;Start a process
  171.     move.l    DosBase(a5),a6
  172.     lea    ResidentCode(a5),a0
  173.     lea    EntryPoint(pc),a1
  174.     move.l    a0,(a1)
  175.     lea    ProcName-StartAllocCode+ResidentCode(a5),a0
  176.     lea    ProcNamePtr(pc),a1
  177.     move.l    a0,(a1)
  178.     lea    NewProcTags(pc),a0
  179.     move.l    a0,d1
  180.     SYS    CreateNewProc
  181.  
  182. ;Exit back to CLI
  183. .Exit:    moveq    #0,d0
  184.     rts
  185.  
  186. ***************************************************************************
  187. * The following code is copied into allocated memory.                     *
  188. ***************************************************************************
  189.  
  190. StartAllocCode:
  191.     move.l    4,a6
  192.     move.l    GlobalPtr(pc),a5
  193.     lea    IntRoutine(pc),a0
  194.     move.l    a0,InputInterrupt+IS_CODE(a5)
  195.  
  196. ;Initialize damping constant.
  197.     move.l    AccelOption(a5),d0
  198.     beq    .NoDamp
  199.     move.l    d0,a0
  200.     move.l    (a0),d0
  201.     subq.l    #1,d0
  202.     move.l    ThreshOption(a5),d1
  203.     beq    .DefThresh
  204.     move.l    d1,a0
  205.     move.l    (a0),d1
  206. .DefThresh:
  207.     addq.l    #1,d1
  208.     mulu.w    d0,d1
  209.     move.w    d1,DampingConstant(a5)
  210. .NoDamp:
  211.  
  212. ;Allocate signals
  213.     moveq    #NumSigs-1,d2
  214.     lea    Sigs(a5),a2
  215. .SigLoop:    moveq    #-1,d0
  216.     SYS    AllocSignal
  217.     tst.l    d0
  218.     bmi    CleanUp
  219.     moveq    #0,d1
  220.     bset    d0,d1
  221.     move.l    d1,(a2)+
  222.     dbra    d2,.SigLoop
  223.  
  224. ;Initialize semaphore(s)
  225.     lea    MySemaphore(a5),a0
  226.     SYS    InitSemaphore
  227.  
  228.     move.l    ThisTask(a6),a0
  229.     move.l    a0,Task(a5)
  230.     move.l    a5,TC_Userdata(a0)
  231.  
  232. ;Install no-flicker option if selected.
  233.     tst.l    FlickerOption(a5)
  234.     beq    .NoFlicker
  235.     move.l    GraphBase(a5),a0
  236.     move.l    gb_copinit(a0),a0
  237.     move.l    a0,OriginalCopInit(a5)
  238.     move.l    ChipData(a5),a1
  239.     lea    Copper(a1),a1
  240.     move.l    a1,a2
  241.     move.w    #MaxCopperSize/4-1,d0
  242. .CLoop:    move.l    (a0)+,d1
  243.     cmp.l    #$008A0000,d1
  244.     beq    .CopEnd
  245.     move.l    d1,(a1)+
  246.     dbra    d0,.CLoop
  247.     clr.l    FlickerOption(a5)
  248.     bra    .NoFlicker
  249. .CopEnd:    move.l    #$01800000,(a1)+
  250.     move.l    #$1607FFFE,(a1)+
  251.     move.w    #$0180,(a1)+
  252.     move.l    #$008A0000,2(a1)
  253.     move.l    a1,RealBackground(a5)
  254.     move.l    a2,cop1lc+_custom
  255.     move.l    GraphBase(a5),a0
  256.     move.l    a2,gb_copinit(a0)
  257.     cmp.w    #color,SysBackground-2(a2)
  258.     bne    .DefColor
  259.     move.w    SysBackground(a2),(a1)
  260.     bra    .NoFlicker
  261. .DefColor:
  262.     move.w    #DefColor,(a1)
  263. .NoFlicker:
  264.  
  265. ;Patch MANY system routines.
  266.     lea    PatchTable(pc),a2
  267.     move.l    a2,a3
  268. .Patch:    move.w    (a2)+,d0    ;get base
  269.     beq    .EndPatch
  270.     move.l    (a5,d0.w),a1    ;library base to patch
  271.     move.w    (a2)+,d0    ;get offset to new routine
  272.     lea    (a3,d0.w),a0
  273.     move.l    a0,d0    ;new routine address
  274.     move.w    (a2)+,a0    ;_LVO offset
  275.     SYS    SetFunction
  276.     move.w    (a2)+,d1
  277.     move.l    d0,(a5,d1.w)
  278.     bra    .Patch
  279. .EndPatch:
  280.  
  281. ;Create an IORequest structure
  282.     SYS    CreateMsgPort
  283.     move.l    d0,InputMsgPort(a5)
  284.     beq    CleanUp
  285.     move.l    d0,a0
  286.     moveq    #IOSTD_SIZE,d0
  287.     SYS    CreateIORequest
  288.     move.l    d0,InputIORequest(a5)
  289.     beq    CleanUp
  290.  
  291. ;Perform NoClick, if desired.
  292.     move.l    NoClickOption(a5),d2
  293.     beq    .Click
  294.     move.l    d2,a0
  295.     move.l    (a0),d2
  296. .Click:    moveq    #0,d3
  297.     moveq    #3,d4
  298. .ClickLoop:
  299.     lea    TrackName(pc),a0    ;device name
  300.     move.l    d3,d0    ;unit number
  301.     move.l    InputIORequest(a5),a1    ;IO request
  302.     moveq    #0,d1    ;flags
  303.     SYS    OpenDevice
  304.     tst.l    d0
  305.     bne    .ECLoop
  306.     move.l    InputIORequest(a5),a1    ;IO request
  307.     move.l    IO_UNIT(a1),a0
  308.     btst    d3,d2
  309.     beq    .SkipNoClick
  310.     bchg    #TDPB_NOCLICK,TDU_PUBFLAGS(a0)
  311. .SkipNoClick:
  312.     tst.l    VerifyOption(a5)
  313.     beq    .SkipVerify
  314.     bchg    #1,TDU_PUBFLAGS(a0)
  315. .SkipVerify:
  316.     SYS    CloseDevice
  317. .ECLoop:    addq.l    #1,d3
  318.     dbra    d4,.ClickLoop
  319.  
  320. ;Handle 'STAR' option.
  321.     tst.l    StarOption(a5)
  322.     beq    .NoStar
  323.     move.l    DosBase(a5),a0
  324.     move.l    dl_Root(a0),a0
  325.     bchg    #0,rn_Flags(a0)
  326. .NoStar:
  327.  
  328. ;Open the input.device
  329.     lea    InputName(pc),a0    ;device name
  330.     moveq    #0,d0    ;unit number
  331.     move.l    InputIORequest(a5),a1    ;IO request
  332.     moveq    #0,d1    ;flags
  333.     SYS    OpenDevice
  334.     tst.l    d0
  335.     bne    CleanUp
  336.  
  337. ;Install input handler
  338.     move.l    InputIORequest(a5),a1
  339.     move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  340.     lea    InputInterrupt(a5),a0
  341.     move.l    a0,IO_DATA(a1)
  342.     SYS    DoIO
  343.     tst.l    d0
  344.     bne    CleanUp
  345.     st    HandlerInstalled(a5)
  346.  
  347. ;Wait for signal(s)
  348. Wait:
  349.     lea    Sigs(a5),a0
  350.     move.l    (a0)+,d0
  351.     moveq    #NumSigs-2,d1
  352. ..    add.l    (a0)+,d0
  353.     dbra    d1,..
  354.     move.l    4,a6
  355.     SYS    Wait
  356.     move.l    d0,d1
  357.     and.l    QuitSig(a5),d1
  358.     bne    SafeCleanUp
  359.     move.l    IntBase(a5),a6
  360.     move.l    d0,d1
  361.     and.l    CLISig(a5),d1
  362.     bne    .Execute
  363.     move.l    d0,d1
  364.     and.l    WBenchToFrontSig(a5),d1
  365.     bne    .WBenchToFront
  366.  
  367. ;Perform ScreenToBack
  368.     move.l    ScreenPtr(a5),d0
  369.     beq    Wait
  370.     clr.l    ScreenPtr(a5)
  371.     move.l    d0,a0
  372.     SYS    ScreenToBack
  373.     bra    Wait
  374. .WBenchToFront:
  375.     SYS    WBenchToFront
  376.     bra    Wait
  377. .Execute:
  378. ;Execute the desired command
  379.     SYS    WBenchToFront
  380.     move.l    DosBase(a5),a6
  381.  
  382.     move.l    CmdOption(a5),d1
  383.     beq    Wait
  384.     lea    .Tags(pc),a0
  385.     move.l    a0,d2    ;tags
  386.     SYS    SystemTagList
  387.     bra    Wait
  388. .Tags:    dc.l    SYS_UserShell,0
  389.     dc.l    NP_StackSize
  390. CmdStackSize:
  391.     dc.l    0
  392.     dc.l    0    ;end of tag list
  393.  
  394. SafeCleanUp:
  395. ;Make sure the SetFunction'ed vectors are still intact.
  396.     lea    PatchTable(pc),a0
  397.     move.l    a0,a2
  398. .Safe:    move.w    (a0)+,d0
  399.     beq    CleanUp
  400.     move.l    (a5,d0.w),a1    ;library base
  401.     move.w    (a0)+,d0
  402.     lea    (a2,d0.w),a3    ;address of new routine
  403.     move.w    (a0)+,d0
  404.     cmp.l    2(a1,d0.w),a3
  405.     bne    Wait
  406.     addq.l    #2,a0
  407.     bra    .Safe
  408.  
  409. LibTable:    dc.w    DosName-LibTable
  410.     dc.w    DosBase
  411.     dc.w    IntName-LibTable
  412.     dc.w    IntBase
  413.     dc.w    LayersName-LibTable
  414.     dc.w    LayersBase
  415.     dc.w    GraphName-LibTable
  416.     dc.w    GraphBase
  417. EndLibTable:
  418.  
  419. NumLibs    equ    (EndLibTable-LibTable)/4
  420.  
  421. CleanUp:
  422.  
  423. ;Enter with global ptr in A5
  424.  
  425.     move.l    4,a6
  426.  
  427. ;Remove input handler, if installed.
  428.     tst.b    HandlerInstalled(a5)
  429.     beq    .SkipHand
  430.     move.l    InputIORequest(a5),a1
  431.     move.w    #IND_REMHANDLER,IO_COMMAND(a1)
  432.     lea    InputInterrupt(a5),a0
  433.     move.l    a0,IO_DATA(a1)
  434.     SYS    DoIO
  435. .SkipHand:
  436.  
  437.     tst.l    OldCloseScreen(a5)
  438.     beq    .SkipRestore
  439.  
  440.     bsr    RestoreMouse
  441.     bsr    RestoreScreen
  442.  
  443. ;Restore original vectors.
  444.  
  445.     lea    PatchTable(pc),a2
  446. .RestoreVecs:
  447.     move.w    (a2),d0
  448.     beq    .SkipRestore
  449.     addq.l    #4,a2    ;skip new routine info
  450.     move.l    (a5,d0.w),a1    ;get library base
  451.     move.w    (a2)+,a0    ;get _LVO
  452.     move.w    (a2)+,d0
  453.     move.l    (a5,d0.w),d0    ;old routine
  454.     SYS    SetFunction
  455.     bra    .RestoreVecs
  456. .SkipRestore:
  457.  
  458. ;Delay for 1/10 second to ensure that no-one is using the patch code.
  459.     move.l    DosBase(a5),d0
  460.     beq    .SkipFreeArg
  461.     move.l    d0,a6
  462.     moveq    #5,d1
  463.     SYS    Delay
  464.  
  465. ;Free argument structure
  466.     move.l    ArgPtr(a5),d1
  467.     beq    .SkipFreeArg
  468.     SYS    FreeArgs
  469. .SkipFreeArg:
  470.  
  471.     move.l    4,a6
  472.  
  473. ;Free signals
  474.     lea    Sigs(a5),a2
  475.     moveq    #NumSigs-1,d2
  476. .SigLoop:    move.l    (a2)+,d1
  477.     beq    .NextSig
  478.     moveq    #-1,d0
  479. .BitLoop:    addq.l    #1,d0
  480.     btst    d0,d1
  481.     beq    .BitLoop
  482.     SYS    FreeSignal
  483. .NextSig:    dbra    d2,.SigLoop
  484.  
  485. ;Remove flicker option, if selected.
  486.     tst.l    FlickerOption(a5)
  487.     beq    .SkipFlicker
  488.     move.l    OriginalCopInit(a5),a0
  489.     move.l    GraphBase(a5),a2
  490.     move.l    gb_copinit(a2),a1
  491. .CLoop:    move.l    (a1)+,(a0)+
  492.     cmp.l    #$008A0000,(a0)
  493.     bne    .CLoop
  494.     move.l    OriginalCopInit(a5),gb_copinit(a2)
  495.     move.l    OriginalCopInit(a5),cop1lc+_custom
  496. .SkipFlicker:
  497.  
  498. ;Close libraries
  499.     lea    LibTable+2(pc),a2
  500.     moveq    #NumLibs-1,d2
  501. .CLibLoop:
  502.     move.w    (a2),a0
  503.     add.l    a5,a0
  504.     tst.l    (a0)
  505.     beq    .SkipClose
  506.     move.l    (a0),a1
  507.     SYS    CloseLibrary
  508. .SkipClose:
  509.     addq.l    #4,a2
  510.     dbra    d2,.CLibLoop
  511.  
  512. ;Close input.device
  513.     move.l    InputIORequest(a5),d0
  514.     beq    .SkipCloseDev
  515.     move.l    d0,a1
  516.     tst.b    IO_ERROR(a1)    ;was there an error?
  517.     bne    .SkipCloseDev    ;yes, don't close
  518.     SYS    CloseDevice
  519. .SkipCloseDev:
  520.  
  521. ;Delete IORequest structure
  522.     move.l    InputIORequest(a5),a0
  523.     SYS    DeleteIORequest
  524.     move.l    InputMsgPort(a5),a0
  525.     SYS    DeleteMsgPort
  526.  
  527. ;Free chip data.
  528.     move.l    ChipData(a5),d0
  529.     beq    .SkipChipData
  530.     move.l    d0,a1
  531.     move.l    #CData_Sizeof,d0
  532.     SYS    FreeMem
  533. .SkipChipData:
  534.  
  535. ;Deallocate global structure. Note that this code is (sometimes) executed
  536. ;within the memory that we are freeing, so we are careful to terminate with
  537. ;a JMP.
  538.     move.l    a5,a1
  539.     move.l    #Data_Sizeof,d0
  540.     jmp    _LVOFreeMem(a6)
  541.  
  542. ;Semaphore routines
  543.  
  544. GetSemaphore:
  545.     movem.l    a0/a6,-(sp)
  546.     move.l    GlobalPtr(pc),a0
  547.     lea    MySemaphore(a0),a0
  548.     move.l    4,a6
  549.     SYS    ObtainSemaphore
  550.     movem.l    (sp)+,a0/a6
  551.     rts
  552. FreeSemaphore:
  553.     movem.l    a0/a6,-(sp)
  554.     move.l    GlobalPtr(pc),a0
  555.     lea    MySemaphore(a0),a0
  556.     move.l    4,a6
  557.     SYS    ReleaseSemaphore
  558.     movem.l    (sp)+,a0/a6
  559.     rts
  560.  
  561. ;****************** SetFunction'ed routines ***************
  562.  
  563. patch    macro
  564.     dc.w    \1
  565.     dc.w    New\2-PatchTable
  566.     dc.w    _LVO\2
  567.     dc.w    Old\2
  568.     endm
  569.  
  570. PatchTable:
  571.     patch    IntBase,CloseScreen
  572.     patch    IntBase,CloseWindow
  573.     patch    IntBase,OpenScreen
  574.     patch    IntBase,ScreenToFront
  575.     patch    IntBase,ScreenToBack
  576.     patch    IntBase,OpenScreenTagList
  577.     patch    IntBase,WBenchToFront
  578.     patch    IntBase,WBenchToBack
  579.     patch    IntBase,SetPointer
  580.     patch    IntBase,ClearPointer
  581.     patch    IntBase,DisplayBeep
  582.     patch    GraphBase,LoadView
  583.     dc.w    0
  584.  
  585. NewDisplayBeep:
  586.     move.l    GlobalPtr(pc),a1
  587.     tst.l    BeepOption(a1)
  588.     bne    .SkipBeep
  589.     move.l    OldDisplayBeep(a1),-(sp)
  590. .SkipBeep:
  591.     rts
  592.  
  593. NewSetPointer:
  594.     bsr    GetSemaphore
  595.     movem.l    d4-d5/a2-a3/a5,-(sp)
  596.     move.l    GlobalPtr(pc),a5
  597.     lea    PointerList(a5),a2
  598.  
  599. ;Find if window is already in table and find empty spot.
  600.     moveq    #POINTERLISTSIZE-1,d4
  601.     sub.l    a3,a3
  602. .WinSearch:
  603.     move.l    pt_Window(a2),d5
  604.     bne    .SkipSave
  605.     move.l    a2,a3
  606. .SkipSave:
  607.     cmp.l    d5,a0
  608.     beq    .Found
  609.     lea    pt_Sizeof(a2),a2
  610.     dbra    d4,.WinSearch
  611.     move.l    a3,a2
  612.     move.l    a2,d4
  613.     beq    .End    ;no room in table, so forget it
  614. .Found:    movem.l    d0-d3/a0-a1,(a2)
  615. .End:    cmp.l    MBlankWindow(a5),a0
  616.     beq    .End1
  617. .SkipMBlank:
  618.     movem.l    (sp)+,d4-d5/a2-a3/a5
  619.     subq.l    #8,sp
  620.     move.l    a0,(sp)
  621.     move.l    GlobalPtr(pc),a0
  622.     move.l    OldSetPointer(a0),4(sp)
  623.     move.l    (sp)+,a0
  624.     bra    FreeSemaphore
  625. .End1:    movem.l    (sp)+,d4-d5/a2-a3/a5
  626.     bra    FreeSemaphore
  627.  
  628. NewClearPointer:
  629.     bsr    GetSemaphore
  630.     move.l    GlobalPtr(pc),a1
  631.     lea    PointerList(a1),a1
  632.     moveq    #POINTERLISTSIZE-1,d0
  633. .ClearLoop:
  634.     cmp.l    pt_Window(a1),a0
  635.     beq    .Found
  636.     lea    pt_Sizeof(a1),a1
  637.     dbra    d0,.ClearLoop
  638.     bra    .End
  639. .Found:    clr.l    pt_Window(a1)
  640. .End:    move.l    GlobalPtr(pc),a1
  641.     cmp.l    MBlankWindow(a1),a0
  642.     beq    .End1
  643. .SkipMBlank:
  644.     move.l    OldClearPointer(a1),-(sp)
  645. .End1:    bra    FreeSemaphore
  646.  
  647. NewLoadView:
  648.     pea    .NewLoad(pc)
  649.     move.l    GlobalPtr(pc),a0
  650.     move.l    OldLoadView(a0),-(sp)
  651.     rts
  652. .NewLoad:
  653.     move.l    GlobalPtr(pc),a0
  654.     tst.l    FlickerOption(a0)
  655.     beq    .End
  656.     move.l    RealBackground(a0),a1
  657.     move.l    GraphBase(a0),a0
  658.     move.l    gb_copinit(a0),a0
  659.     move.w    SysBackground(a0),(a1)
  660. .End:    rts
  661.  
  662. NewCloseScreen:
  663.     bsr    GetSemaphore
  664.     move.l    GlobalPtr(pc),a1
  665.     lea    ScreenList(a1),a1
  666.     moveq    #SCREENLISTSIZE-1,d0
  667. .Loop:    cmp.l    (a1),a0
  668.     beq    .Match
  669.     addq.l    #8,a1
  670.     dbra    d0,.Loop
  671. .End:    move.l    GlobalPtr(pc),a1
  672.     pea    RestoreWindow(pc)
  673.     move.l    OldCloseScreen(a1),-(sp)
  674.     bra    FreeSemaphore
  675. .Match:    clr.l    (a1)
  676.     bra    .End
  677.  
  678. NewCloseWindow:
  679.     bsr    GetSemaphore
  680.     push    a0
  681.     SYS    ClearPointer
  682.     pop    a0
  683.     move.l    GlobalPtr(pc),a1
  684.     cmp.l    MBlankWindow(a1),a0
  685.     bne    .SkipClear
  686.     clr.l    MBlankWindow(a1)
  687. .SkipClear:
  688.     lea    ScreenList+4(a1),a1
  689.     moveq    #SCREENLISTSIZE-1,d0
  690. .Loop:    cmp.l    (a1),a0
  691.     beq    .Match
  692.     addq.l    #8,a1
  693.     dbra    d0,.Loop
  694. .End:    move.l    GlobalPtr(pc),a1
  695.     move.l    OldCloseWindow(a1),-(sp)
  696.     bra    FreeSemaphore
  697. .Match:    clr.l    -4(a1)
  698.     bra    .End
  699.  
  700. MyRemember:
  701.     bsr    GetSemaphore
  702.     bsr    RememberWindow
  703.     move.l    a0,-(sp)
  704.     move.l    GlobalPtr(pc),a0
  705.     move.l    (a0,d0.w),d0
  706.     move.l    (sp)+,a0
  707.     move.l    d0,-(sp)
  708.     bra    FreeSemaphore
  709.  
  710. NewOpenScreen:
  711.     move.w    #OldOpenScreen,d0
  712.     bra    MyRemember
  713. NewOpenScreenTagList:
  714.     move.w    #OldOpenScreenTagList,d0
  715.     bra    MyRemember
  716. NewWBenchToFront:
  717.     move.w    #OldWBenchToFront,d0
  718.     bsr    MyRemember
  719.     bra    RestoreWindow
  720. NewWBenchToBack:
  721.     move.w    #OldWBenchToBack,d0
  722.     bsr    MyRemember
  723.     bra    RestoreWindow
  724. NewScreenToFront:
  725.     move.w    #OldScreenToFront,d0
  726.     bsr    MyRemember
  727.     bra    RestoreWindow
  728. NewScreenToBack:
  729.     move.w    #OldScreenToBack,d0
  730.     bsr    MyRemember
  731.     bra    RestoreWindow
  732.  
  733. ;****************** End of SetFunction'ed routines ***************
  734.  
  735. RememberWindow:
  736.  
  737. ;This routine remembers the currently activated window on the current
  738. ;screen.
  739.  
  740.     movem.l    d0-d1/a0-a2/a4-a6,-(sp)
  741.     move.l    GlobalPtr(pc),a5
  742.     move.l    IntBase(a5),a4
  743.     move.l    4,a6
  744.     SYS    Forbid
  745.     move.l    ib_ActiveScreen(a4),a0
  746.     move.l    ib_ActiveWindow(a4),a2
  747.     SYS    Permit
  748.  
  749. ;Sanity checks
  750.     move.l    a0,d0
  751.     beq    .End
  752.     move.l    a2,d0
  753.     beq    .End
  754.  
  755.     lea    ScreenList(a5),a1
  756.     moveq    #SCREENLISTSIZE-1,d0
  757. .ScLoop:    cmp.l    (a1),a0
  758.     beq    .Match
  759.     addq.l    #8,a1
  760.     dbra    d0,.ScLoop
  761.  
  762. ;Screen not found. Add to screen list.
  763.     lea    ScreenList(a5),a1
  764.     moveq    #SCREENLISTSIZE-1,d0
  765. .AddLoop:    tst.l    (a1)
  766.     beq    .Match
  767.     addq.l    #8,a1
  768.     dbra    d0,.AddLoop
  769.     bra    .End    ;table is full
  770. .Match:
  771.     move.l    a0,(a1)+    ;screen
  772.     move.l    a2,(a1)    ;currently activated window
  773. .End:    movem.l    (sp)+,d0-d1/a0-a2/a4-a6
  774.     rts
  775.  
  776. RestoreWindow:
  777.  
  778. ;This routine restores (re-activates) the previously activated window for
  779. ;this screen.
  780.  
  781.     bsr    GetSemaphore
  782.     movem.l    d0-d1/a0-a1/a6,-(sp)
  783.     move.l    GlobalPtr(pc),a0
  784.     lea    ScreenList(a0),a1
  785.     move.l    IntBase(a0),a6
  786.     move.l    ib_FirstScreen(a6),a0
  787.     move.l    a0,d0
  788.     beq    .End    ;sanity check
  789.     moveq    #SCREENLISTSIZE-1,d0
  790. .Loop:    cmp.l    (a1),a0
  791.     beq    .Match
  792.     addq.l    #8,a1
  793.     dbra    d0,.Loop
  794.     move.l    sc_FirstWindow(a0),a0    ;default window
  795.     move.l    a0,d0
  796.     beq    .End    ;sanity check
  797.     bra    .SkipMatch
  798. .Match:
  799.     move.l    4(a1),a0
  800. .SkipMatch:
  801.     SYS    ActivateWindow
  802. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  803.     bra    FreeSemaphore
  804.  
  805. ;***************************************************************************
  806. ;Start of input handler code
  807. ;***************************************************************************
  808.  
  809. ;Get window associated with current mouse position.
  810. ;Returns Window in D0 and screen in D1.
  811.  
  812. GetWindow:
  813.     movem.l    d2-d4/a0-a1/a4-a6,-(sp)
  814.     move.l    GlobalPtr(pc),a5
  815.     move.l    LayersBase(a5),a6
  816.     move.l    IntBase(a5),a4
  817.     move.l    ib_FirstScreen(a4),d4
  818. .ScLoop:    tst.l    d4
  819.     beq    .ErrEnd
  820.     move.l    d4,a0
  821.     move.l    sc_NextScreen(a0),d4
  822.     move.w    ib_MouseX(a4),d0
  823.     move.w    ib_MouseY(a4),d1
  824.     move.w    sc_ViewPort+vp_Modes(a0),d2
  825.     move.w    d2,d3
  826.     and.w    #V_LACE,d2    ;interlace?
  827.     bne    .Lace    ;yes
  828.     lsr.w    #1,d1
  829. .Lace:    and.w    #V_HIRES,d3    ;hires?
  830.     bne    .Hires    ;yes
  831.     lsr.w    #1,d0
  832. .Hires:    sub.w    sc_ViewPort+vp_DxOffset(a0),d0
  833.     bmi    .ScLoop
  834.     sub.w    sc_ViewPort+vp_DyOffset(a0),d1
  835.     bmi    .ScLoop
  836.     push    a0
  837.     lea    sc_LayerInfo(a0),a0
  838.     SYS    WhichLayer
  839.     pop    d1
  840.     tst.l    d0
  841.     beq    .End
  842.     move.l    d0,a0
  843.     move.l    lr_Window(a0),d0
  844. .End:    movem.l    (sp)+,d2-d4/a0-a1/a4-a6
  845.     rts
  846. .ErrEnd:    moveq    #0,d0
  847.     moveq    #0,d1
  848.     bra    .End
  849.  
  850. DoWindowToFront:
  851.  
  852. ;Perform a WindowToFront on the window in D0.
  853. ;Enter with global ptr in A1.
  854.  
  855.     tst.l    d0
  856.     beq    .End1
  857.     movem.l    d0-d1/a0-a1/a6,-(sp)
  858.     move.l    IntBase(a1),a6
  859.     move.l    d0,a0
  860.     move.l    wd_WLayer(a0),a1
  861.     move.l    a1,d0
  862.     beq    .End
  863.     move.l    lr_ClipRect(a1),a1
  864.     move.l    a1,d0
  865.     beq    .End
  866.     tst.l    (a1)
  867.     beq    .End
  868.     move.l    wd_Flags(a0),d0
  869.     and.l    #WFLG_BACKDROP,d0
  870.     bne    .End
  871.     SYS    WindowToFront
  872. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  873. .End1:    rts
  874.  
  875. BlankMouse:
  876.     movem.l    d0-d3/a0-a1/a5-a6,-(sp)
  877.     move.l    GlobalPtr(pc),a5
  878.     move.l    IntBase(a5),a6
  879.     move.l    ib_ActiveWindow(a6),d0
  880.     beq    .End
  881.     cmp.l    MBlankWindow(a5),d0
  882.     beq    .End
  883.     move.l    d0,MBlankWindow(a5)
  884.     move.l    d0,a0
  885.     move.l    ChipData(a5),a1
  886. ;    lea    ZeroMouse(a1),a1    ;not needed
  887.     moveq    #1,d0    ;height
  888.     moveq    #16,d1    ;width
  889.     moveq    #0,d2    ;xoffset
  890.     moveq    #0,d3    ;yoffset
  891.     pea    .End(pc)
  892.     move.l    OldSetPointer(a5),-(sp)
  893.     rts
  894. .End:    movem.l    (sp)+,d0-d3/a0-a1/a5-a6
  895.     rts
  896.  
  897. RestoreMouse:
  898.     movem.l    d0-d1/a0-a2/a5-a6,-(sp)
  899.     move.l    GlobalPtr(pc),a5
  900.     move.l    IntBase(a5),a6
  901.     move.l    MBlankWindow(a5),d0
  902.     beq    .End
  903.  
  904. ;Look for window in pointer table. If present, do a SetPointer to restore
  905. ;the custom pointer. Otherwise call ClearPointer.
  906.  
  907.     move.l    d0,a0
  908.     clr.l    MBlankWindow(a5)
  909.     lea    PointerList(a5),a1
  910.     moveq    #POINTERLISTSIZE-1,d0
  911. .WinLoop:    cmp.l    pt_Window(a1),a0
  912.     beq    .Found
  913.     lea    pt_Sizeof(a1),a1
  914.     dbra    d0,.WinLoop
  915.     pea    .End(pc)
  916.     move.l    OldClearPointer(a5),-(sp)
  917.     rts
  918. .End:    movem.l    (sp)+,d0-d1/a0-a2/a5-a6
  919.     rts
  920. .Found:    move.l    a1,a2
  921.     movem.l    (a2),d0-d3/a0-a1
  922.     pea    .End(pc)
  923.     move.l    OldSetPointer(a5),-(sp)
  924.     rts
  925.  
  926. RestoreScreen:
  927.     push    a5
  928.     move.l    GlobalPtr(pc),a5
  929.     bclr    #STB_SBlanked,Status(a5)
  930.     beq    .End
  931.     move.w    #DMAF_SETCLR+DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  932. .End:    pop    a5
  933.     rts
  934.  
  935. SigTask:
  936. ;Enter with GlobalPtr in A1 and signal in D0.
  937.     movem.l    d0-d1/a0-a1/a6,-(sp)
  938.     move.l    Task(a1),a1
  939.     move.l    4,a6
  940.     SYS    Signal
  941.     movem.l    (sp)+,d0-d1/a0-a1/a6
  942.     rts
  943.  
  944. ;**************************** Input handler *********************************
  945.  
  946. IntRoutine:
  947.     movem.l    a2/a6,-(sp)
  948.     move.l    IntBase(a1),a6
  949.     bsr    GetSemaphore
  950.     move.l    a0,-(sp)
  951.  
  952. ;Handle NoFlicker option
  953.     tst.l    FlickerOption(a1)
  954.     beq    .SkipFlick
  955.     move.l    GraphBase(a1),a2
  956.     move.l    gb_copinit(a2),a0
  957.     move.l    gb_LOFlist(a2),a2
  958.     cmp.b    #WaitLine-1,WindowStart(a2)
  959.     blo    .DisableNF
  960.     move.b    #WaitLine,WaitLineOffset(a0)
  961.     bra    .SkipDisableNF
  962. .DisableNF:
  963.     clr.b    WaitLineOffset(a0)
  964. .SkipDisableNF:
  965.     cmp.w    #color,SysBackground-2(a0)
  966.     bne    .DefColor
  967.     move.w    SysBackground(a0),d0
  968.     move.l    RealBackground(a1),a0
  969.     move.w    d0,(a0)
  970.     bra    .SkipColor
  971. .DefColor:
  972.     move.l    RealBackground(a1),a0
  973.     move.w    #DefColor,(a0)
  974. .SkipColor:
  975.     move.l    (sp),a0
  976. .SkipFlick:
  977.  
  978. ;Perform SunMouse
  979.     tst.l    SunMouseOption(a1)
  980.     beq    .SkipSunMouse1
  981.     cmp.b    #IECLASS_RAWMOUSE,ie_Class(a0)
  982.     beq    .SkipSunMouse1
  983.     bclr    #STB_SunMouse,Status(a1)
  984.     beq    .SkipSunMouse1
  985.     bsr    GetWindow
  986.     movem.l    a0-a1,-(sp)
  987.     move.l    d0,a0
  988.     cmp.l    ib_ActiveWindow(a6),a0
  989.     beq    .EndSun
  990.     SYS    ActivateWindow
  991. .EndSun:    movem.l    (sp)+,a0-a1
  992. .SkipSunMouse1:
  993.  
  994.     move.l    MBlankWindow(a1),d0
  995.     beq    .Loop
  996.     cmp.l    ib_ActiveWindow(a6),d0
  997.     beq    .EndMBW
  998.     bsr    RestoreMouse
  999.     bsr    BlankMouse
  1000. .EndMBW:
  1001.  
  1002. .Loop:    cmp.b    #IECLASS_TIMER,ie_Class(a0)
  1003.     beq    .NotKey
  1004.  
  1005. ;Reset screen blank
  1006.     tst.l    SBlankOption(a1)
  1007.     beq    .SkipSRestore
  1008.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1009.     bsr    RestoreScreen
  1010. .SkipSRestore:
  1011.  
  1012.     cmp.b    #IECLASS_RAWKEY,ie_Class(a0)
  1013.     bne    .NotKey
  1014.     tst.b    ie_Code+1(a0)
  1015.     bmi    .Next    ;ignore up key codes
  1016.  
  1017. ;Do Northgate keyboard mapping.
  1018.     tst.l    NorthGateOption(a1)
  1019.     beq    .SkipNorthgate
  1020.     lea    NorthgateTable(pc),a2
  1021.     move.w    ie_Code(a0),d0
  1022.     bclr    #7,d0
  1023. .NorthgateLoop:
  1024.     move.b    (a2),d1
  1025.     beq    .EndNorthgate
  1026.     addq.l    #3,a2
  1027.     cmp.b    d0,d1
  1028.     bne    .NorthgateLoop
  1029.     and.w    #$80,ie_Code(a0)
  1030.     move.b    -2(a2),d0
  1031.     or.b    d0,ie_Code+1(a0)
  1032.     move.b    -1(a2),d0
  1033.     bmi    .EndNorthgate
  1034.     bset    d0,ie_Qualifier+1(a0)
  1035. .EndNorthgate:
  1036. .SkipNorthgate:
  1037.  
  1038.     btst    #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
  1039.     bne    .DoLAmiga
  1040.  
  1041. ;Blank mouse pointer
  1042.     tst.l    MBlankOption(a1)
  1043.     beq    .NoMBlank
  1044.     bsr    BlankMouse
  1045. .NoMBlank:
  1046.     bra    .Next
  1047.  
  1048. .DoLAmiga:
  1049.     cmp.w    #$37,ie_Code(a0)    ;'m'?
  1050.     bne    .NotM
  1051.  
  1052. ;We found an Amiga-M. Defuse and perform action.
  1053.     clr.b    ie_Class(a0)
  1054.     move.l    ib_FirstScreen(a6),a0
  1055.     move.l    a0,d0
  1056.     beq    .EndM    ;sanity check
  1057.     move.l    a0,ScreenPtr(a1)
  1058.     move.l    ScreenToBackSig(a1),d0
  1059.     bsr    SigTask
  1060. .EndM:    bra    .End
  1061. .NotM:
  1062.     cmp.w    #$36,ie_Code(a0)    ;'n'?
  1063.     bne    .NotN
  1064.  
  1065. ;We found an Amiga-N. Defuse and perform action.
  1066.     clr.b    ie_Class(a0)
  1067.     move.l    WBenchToFrontSig(a1),d0
  1068.     bsr    SigTask
  1069.     bra    .End
  1070. .NotN:
  1071.     tst.l    CmdOption(a1)
  1072.     beq    .Next
  1073.     cmp.w    #$45,ie_Code(a0)    ;ESC?
  1074.     bne    .Next
  1075.     clr.b    ie_Class(a0)
  1076.     move.l    CLISig(a1),d0
  1077.     bsr    SigTask
  1078.     bra    .End
  1079.  
  1080. .NotKey:
  1081.     move.w    ib_MouseX(a6),d0
  1082.     move.w    ib_MouseY(a6),d1
  1083.     cmp.b    #IECLASS_RAWMOUSE,ie_Class(a0)
  1084.     beq    .DoMouse
  1085.     cmp.w    CurrentX(a1),d0
  1086.     bne    .DoMouse
  1087.     cmp.w    CurrentY(a1),d1
  1088.     beq    .Next
  1089.  
  1090. .DoMouse:
  1091.     move.w    d0,CurrentX(a1)
  1092.     move.w    d1,CurrentY(a1)
  1093.     tst.l    MBlankOption(a1)
  1094.     beq    .NoRestore
  1095.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1096.     bsr    RestoreMouse
  1097. .NoRestore:
  1098.  
  1099. ;Perform SunMouse
  1100.     tst.l    SunMouseOption(a1)
  1101.     beq    .SkipSunMouse
  1102.     move.w    ie_Qualifier(a0),d0
  1103.     and.w    #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
  1104.     bne    .SkipSunMouse
  1105.     cmp.w    #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
  1106.     beq    .SkipSunMouse
  1107.     bset    #STB_SunMouse,Status(a1)
  1108. .SkipSunMouse:
  1109.  
  1110. ;Perform click-to-back.
  1111.     tst.l    CTBOption(a1)
  1112.     beq    .NoCTB
  1113.     cmp.w    #IECODE_RBUTTON,ie_Code(a0)
  1114.     bne    .NoCTB
  1115.     move.w    ie_Qualifier(a0),d0
  1116.     btst    #IEQUALIFIERB_LEFTBUTTON,d0
  1117.     beq    .NoCTB
  1118.  
  1119.     movem.l    d2/a0-a1,-(sp)
  1120.     bsr    GetWindow
  1121.     tst.l    d0
  1122.     beq    .FlipScreen
  1123.     move.l    d0,a1
  1124.     move.l    wd_Flags(a1),d2
  1125.     and.l    #WFLG_BACKDROP,d2
  1126.     bne    .FlipScreen
  1127.  
  1128. ;Is this the only window on this screen, except for backdrop windows?
  1129.     move.l    wd_WScreen(a1),a1
  1130.     move.l    sc_FirstWindow(a1),a1
  1131. .BackLoop:
  1132.     cmp.l    a1,d0
  1133.     beq    .EBackLoop
  1134.     move.l    wd_Flags(a1),d2
  1135.     and.l    #WFLG_BACKDROP,d2
  1136.     beq    .FlipWindow
  1137. .EBackLoop:
  1138.     move.l    (a1),a1
  1139.     move.l    a1,d2
  1140.     bne    .BackLoop
  1141. .FlipScreen:
  1142.     tst.l    d1
  1143.     beq    .ECTB
  1144.     move.l    GlobalPtr(pc),a1
  1145.     move.l    d1,ScreenPtr(a1)
  1146.     move.l    ScreenToBackSig(a1),d0
  1147.     bsr    SigTask
  1148.     bra    .ECTB
  1149. .FlipWindow:
  1150.     move.l    d0,a0
  1151.     SYS    WindowToBack
  1152.  
  1153. .ECTB:    movem.l    (sp)+,d2/a0-a1
  1154.     clr.b    ie_Class(a0)
  1155.     bra    .Next
  1156. .NoCTB:
  1157.  
  1158. ;Perform click-to-front.
  1159.     tst.l    CTFOption(a1)
  1160.     beq    .NoCTF
  1161.     cmp.w    #IECODE_LBUTTON,ie_Code(a0)
  1162.     bne    .NoCTF
  1163.     bsr    GetWindow
  1164.     tst.l    d0
  1165.     beq    .NoCTF
  1166.     move.l    CTFOption(a1),a2
  1167.     move.l    (a2),d1
  1168.     cmp.l    #1,d1
  1169.     bhi    .MoreThanOne
  1170.     bsr    DoWindowToFront
  1171.     bra    .NoCTF
  1172. .MoreThanOne:
  1173.     cmp.l    ClickWindow(a1),d0
  1174.     beq    .SameWindow
  1175.     move.l    d0,ClickWindow(a1)
  1176.     moveq    #1,d0
  1177.     move.l    d0,ClickCount(a1)
  1178. .Time:    move.l    ie_TimeStamp+TV_SECS(a0),ClickTime+TV_SECS(a1)
  1179.     move.l    ie_TimeStamp+TV_MICRO(a0),ClickTime+TV_MICRO(a1)
  1180.     bra    .NoCTF
  1181. .SameWindow:
  1182.  
  1183. ;Check to see whether MaxClickDelay has been exceeded. If not, increment
  1184. ;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
  1185. ;Window under pointer in D0.
  1186.  
  1187.     push    d0
  1188.     movem.l    d2-d3/a0-a1,-(sp)
  1189.     move.l    ClickTime+TV_SECS(a1),d0
  1190.     move.l    ClickTime+TV_MICRO(a1),d1
  1191.     move.l    ie_TimeStamp+TV_SECS(a0),d2
  1192.     move.l    ie_TimeStamp+TV_MICRO(a0),d3
  1193.     SYS    DoubleClick
  1194.     movem.l    (sp)+,d2-d3/a0-a1
  1195.     tst.l    d0
  1196.     beq    .TimeExceeded
  1197.     addq.l    #1,ClickCount(a1)
  1198.     push    a0
  1199.     move.l    CTFOption(a1),a0
  1200.     move.l    (a0),d0
  1201.     pop    a0
  1202.     cmp.l    ClickCount(a1),d0
  1203.     bhi    .NeedMoreClicks
  1204.     clr.l    ClickCount(a1)
  1205.     pop    d0
  1206.     bsr    DoWindowToFront
  1207.     bra    .NoCTF
  1208. .TimeExceeded:
  1209.     moveq    #1,d0
  1210.     move.l    d0,ClickCount(a1)
  1211. .NeedMoreClicks:
  1212.     pop    d0
  1213.     bra    .Time
  1214. .NoCTF:
  1215.  
  1216. ;Perform acceleration.
  1217.     tst.l    AccelOption(a1)
  1218.     beq    .Next
  1219.  
  1220.     moveq    #0,d0
  1221.     tst.l    ThreshOption(a1)
  1222.     beq    .T1
  1223.     move.l    ThreshOption(a1),a2
  1224.     move.l    (a2),d0
  1225. .T1:    move.w    ie_X(a0),d1
  1226.     bpl    .PosX
  1227.     neg.w    d1
  1228. .PosX:    cmp.w    d0,d1
  1229.     bls    .SkipX    ;below threshold
  1230.     move.l    AccelOption(a1),a2
  1231.     move.l    (a2),d1
  1232.     muls.w    ie_X(a0),d1
  1233.     bpl    .SubDampX
  1234.     add.w    DampingConstant(a1),d1
  1235.     bra    .DampX
  1236. .SubDampX:
  1237.     sub.w    DampingConstant(a1),d1
  1238. .DampX:    move.w    d1,ie_X(a0)
  1239. .SkipX:    move.w    ie_Y(a0),d1
  1240.     bpl    .PosY
  1241.     neg.w    d1
  1242. .PosY:    cmp.w    d0,d1
  1243.     bls    .EndAccel
  1244.     move.l    AccelOption(a1),a2
  1245.     move.l    (a2),d1
  1246.     muls.w    ie_Y(a0),d1
  1247.     bpl    .SubDampY
  1248.     add.w    DampingConstant(a1),d1
  1249.     bra    .DampY
  1250. .SubDampY:
  1251.     sub.w    DampingConstant(a1),d1
  1252.  
  1253. .DampY:    move.w    d1,ie_Y(a0)
  1254. .EndAccel:
  1255.  
  1256. .Next:    move.l    a0,d1
  1257.     move.l    (a0),d0
  1258.     move.l    d0,a0
  1259.     bne    .Loop
  1260.  
  1261. ;Check for time-outs (mouse and screen blanking)
  1262.     move.l    d1,a0
  1263.     tst.l    MBlankOption(a1)
  1264.     beq    .NoMTime
  1265.     move.l    MBlankOption(a1),a0
  1266.     move.l    (a0),d0    ;get value in seconds
  1267.     move.l    d1,a0
  1268.     move.l    ie_TimeStamp(a0),d1
  1269.     tst.l    MouseTime(a1)
  1270.     beq    .InitMBlank
  1271.     sub.l    MouseTime(a1),d1
  1272.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1273.     blo    .NoMTime
  1274.     bsr    BlankMouse
  1275. .NoMTime:
  1276.     tst.l    SBlankOption(a1)
  1277.     beq    .End
  1278.     btst    #STB_SBlanked,Status(a1)
  1279.     bne    .End
  1280.     push    a0
  1281.     move.l    SBlankOption(a1),a0
  1282.     move.l    (a0),d0    ;get value in seconds
  1283.     pop    a0
  1284.     move.l    ie_TimeStamp(a0),d1
  1285.     tst.l    ScreenTime(a1)
  1286.     beq    .InitSBlank
  1287.     sub.l    ScreenTime(a1),d1
  1288.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1289.     blo    .End
  1290.     move.w    #DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  1291.     clr.w    color+_custom
  1292.     bset    #STB_SBlanked,Status(a1)
  1293.  
  1294. .End:    move.l    (sp)+,d0
  1295.     bsr    FreeSemaphore
  1296.     movem.l    (sp)+,a2/a6
  1297.     rts
  1298. .InitMBlank:
  1299.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1300.     bra    .NoMTime
  1301. .InitSBlank:
  1302.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1303.     bra    .End
  1304.  
  1305. GlobalPtr:
  1306.     dc.l    0
  1307.  
  1308. NorthgateTable:
  1309.     dc.b    $6b,$4f,IEQUALIFIERB_LSHIFT
  1310.     dc.b    $6c,$4e,IEQUALIFIERB_LSHIFT
  1311.     dc.b    $6d,$4c,IEQUALIFIERB_LSHIFT
  1312.     dc.b    $6e,$4d,IEQUALIFIERB_LSHIFT
  1313.     dc.b    0
  1314.  
  1315. ProcName:    dc.b    'QMouse process',0
  1316. InputName:
  1317.     dc.b    'input.device',0
  1318. TrackName:
  1319.     dc.b    'trackdisk.device',0
  1320.     even
  1321.  
  1322. EndAllocCode:    ;end of code copied into allocated memory
  1323. ;***********************************************************************
  1324.  
  1325. NewProcTags:
  1326.     dc.l    NP_Entry
  1327. EntryPoint:
  1328.     dc.l    0
  1329.     dc.l    NP_Name
  1330. ProcNamePtr:
  1331.     dc.l    0
  1332.     dc.l    NP_Cli,-1
  1333.     dc.l    0    ;end of tags
  1334.  
  1335. Template:    dc.b    'M=MBLANK/K/N,'
  1336.     dc.b    'S=SBLANK/K/N,'
  1337.     dc.b    'N=NOFLICKER/S,'
  1338.     dc.b    'CMD/K,'
  1339.     dc.b    'A=ACCELERATION/K/N,'
  1340.     dc.b    'T=THRESHOLD/K/N,'
  1341.     dc.b    'CTB=CLICKTOBACK/S,'
  1342.     dc.b    'CTF=CLICKTOFRONT/K/N,'
  1343.     dc.b    'SUNMOUSE/S,'
  1344.     dc.b    'NORTHGATE/S,'
  1345.     dc.b    'NOBEEP/S,'
  1346.     dc.b    'NOCLICK/K/N,'
  1347.     dc.b    'VERIFY/S,'
  1348.     dc.b    'STAR/S,'
  1349.     dc.b    'QUIT/S',0
  1350.  
  1351. IntName:    dc.b    'intuition.library',0
  1352. GraphName:
  1353.     dc.b    'graphics.library',0
  1354. DosName:    dc.b    'dos.library',0
  1355. LayersName:
  1356.     dc.b    'layers.library',0
  1357.  
  1358. ;The ordering here is special: data registers first, then address
  1359. ;registers, so that MOVEM may be used to save/restore the data.
  1360.  
  1361.     STRUCTURE    pt,0
  1362.     LONG    pt_Height
  1363.     LONG    pt_Width
  1364.     LONG    pt_XOffset
  1365.     LONG    pt_YOffset
  1366.     LONG    pt_Window
  1367.     LONG    pt_Pointer
  1368.     LABEL    pt_Sizeof
  1369.  
  1370. ResidentCodeSize    equ    EndAllocCode-StartAllocCode
  1371.  
  1372.     STRUCTURE    Data,0
  1373.     WORD    Nothing    ;to make zero special
  1374.     LONG    Task
  1375.     LONG    InputMsgPort
  1376.     LONG    InputIORequest
  1377.     STRUCT    InputInterrupt,IS_SIZE
  1378.     LONG    IntBase
  1379.     LONG    GraphBase
  1380.     LONG    LayersBase
  1381.     STRUCT    ScreenList,SCREENLISTSIZE*8
  1382.     STRUCT    PointerList,POINTERLISTSIZE*pt_Sizeof
  1383.     LONG    OldCloseScreen
  1384.     LONG    OldCloseWindow
  1385.     LONG    OldScreenToFront
  1386.     LONG    OldScreenToBack
  1387.     LONG    OldOpenScreen
  1388.     LONG    OldOpenScreenTagList
  1389.     LONG    OldWBenchToFront
  1390.     LONG    OldWBenchToBack
  1391.     LONG    OldLoadView
  1392.     LONG    OldSetPointer
  1393.     LONG    OldClearPointer
  1394.     LONG    OldDisplayBeep
  1395.     LONG    DosBase
  1396.     LONG    ArgPtr
  1397.     STRUCT    ResidentCode,ResidentCodeSize
  1398.     LONG    MouseTime    ;timeout for mouse blanking
  1399.     LONG    ScreenTime    ;for screen blanking
  1400.     LONG    MBlankWindow
  1401.     WORD    DampingConstant
  1402.     STRUCT    MySemaphore,SS_SIZE
  1403.     LONG    ClickWindow
  1404.     STRUCT    ClickTime,TV_SIZE
  1405.     LONG    ClickCount
  1406.     LONG    Path
  1407.     LONG    ChipData
  1408.     LONG    RealBackground
  1409.     LONG    OriginalCopInit
  1410.     LONG    ScreenPtr
  1411.     WORD    CurrentX
  1412.     WORD    CurrentY
  1413.  
  1414.     LABEL    Sigs
  1415.     LONG    CLISig
  1416.     LONG    QuitSig
  1417.     LONG    ScreenToBackSig
  1418.     LONG    WBenchToFrontSig
  1419.     LABEL    EndSigs
  1420.  
  1421.     LABEL    Options
  1422.     LONG    MBlankOption
  1423.     LONG    SBlankOption
  1424.     LONG    FlickerOption
  1425.     LONG    CmdOption
  1426.     LONG    AccelOption
  1427.     LONG    ThreshOption
  1428.     LONG    CTBOption
  1429.     LONG    CTFOption
  1430.     LONG    SunMouseOption
  1431.     LONG    NorthGateOption
  1432.     LONG    BeepOption
  1433.     LONG    NoClickOption
  1434.     LONG    VerifyOption
  1435.     LONG    StarOption
  1436.     LONG    QuitOption
  1437.  
  1438.     BYTE    HandlerInstalled
  1439.     BYTE    Status    ;various status bits (defined below)
  1440.     LABEL    Data_Sizeof
  1441.  
  1442. ;Bit definitions for Status
  1443.     BITDEF    ST,SBlanked,0
  1444.     BITDEF    ST,SunMouse,1
  1445.  
  1446. NumSigs    equ    (EndSigs-Sigs)/4
  1447.  
  1448.     STRUCTURE    CData,0
  1449.     STRUCT    ZeroMouse,12
  1450.     STRUCT    Copper,MaxCopperSize+4*4
  1451.     LABEL    CData_Sizeof
  1452.  
  1453.     end
  1454.